/*
 * Copyright (c) 2009, Hamish Morgan. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the University of Sussex nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * PicCatView.java
 */
package piccat.view;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GraphicsDevice;
import java.awt.Toolkit;
import java.io.IOException;
import org.jdesktop.application.Action;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.FrameView;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.Map;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import org.jdesktop.application.Application;
import org.jdesktop.application.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import piccat.diamondtouch.DTHandler;
import piccat.model.GameFactory;
import piccat.model.GameLoadException;
import piccat.model.Game;

/**
 * The application's main frame.
 *
 * @author Hamish Morgan
 */
public class PicCatView extends FrameView {

    private static final int KEY_MASK = Toolkit.getDefaultToolkit().
            getMenuShortcutKeyMask();
    private static final Logger LOG =
            LoggerFactory.getLogger(PicCatView.class);
    private GameView gameView;
    private DTHandler dtHandler;

    public PicCatView(SingleFrameApplication app) {
        super(app);

        initComponents();

        loadNewGameItems();
        try {
            dtHandler = new DTHandler(3333);
            dtHandler.start();
        } catch (IOException ex) {
            LOG.error("Failed to start DT Handler", ex);
        }

    }

    private void loadNewGameItems() {
        try {
            final Map<String, String> gameMap =
                    GameFactory.getGameNames();
            for (final String displayText : gameMap.keySet()) {
                final String setName = gameMap.get(displayText);
                final JMenuItem item = new JMenuItem();
                item.setText(displayText);
                item.addActionListener(new ActionListener() {

                    public void actionPerformed(ActionEvent e) {
                        new NewGameTask(setName, 2, getApplication()).execute();
                    }
                });
                newDoubleGameMenu.add(item);
                final JMenuItem item2 = new JMenuItem();
                item2.setText(displayText);
                item2.addActionListener(new ActionListener() {

                    public void actionPerformed(ActionEvent e) {
                        new NewGameTask(setName, 1, getApplication()).execute();
                    }
                });
                newSingleGameMenu.add(item2);
            }
        } catch (GameLoadException ex) {
            String message = "Failed to load the new game menu items: ";
            LOG.error(message, ex);
            JOptionPane.showMessageDialog(getFrame(), "<html>" + message +
                    "<br />" + ex.getMessage(), "Error",
                    JOptionPane.ERROR_MESSAGE);
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        mainPanel = new javax.swing.JPanel();
        noGamePanel = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        menuBar = new javax.swing.JMenuBar();
        javax.swing.JMenu fileMenu = new javax.swing.JMenu();
        newDoubleGameMenu = new javax.swing.JMenu();
        newSingleGameMenu = new javax.swing.JMenu();
        closeMenuItem = new javax.swing.JMenuItem();
        javax.swing.JMenuItem exitMenuItem = new javax.swing.JMenuItem();
        jMenu1 = new javax.swing.JMenu();
        jCheckBoxMenuItem1 = new javax.swing.JCheckBoxMenuItem();

        mainPanel.setMinimumSize(new java.awt.Dimension(640, 480));
        mainPanel.setName("mainPanel"); // NOI18N
        mainPanel.setPreferredSize(new java.awt.Dimension(640, 480));
        mainPanel.setLayout(new java.awt.BorderLayout());

        noGamePanel.setMinimumSize(new java.awt.Dimension(640, 480));
        noGamePanel.setName("noGamePanel"); // NOI18N
        noGamePanel.setPreferredSize(new java.awt.Dimension(640, 480));

        jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(piccat.view.PicCatApp.class).getContext().getResourceMap(PicCatView.class);
        jLabel1.setText(resourceMap.getString("jLabel1.text")); // NOI18N
        jLabel1.setName("jLabel1"); // NOI18N

        org.jdesktop.layout.GroupLayout noGamePanelLayout = new org.jdesktop.layout.GroupLayout(noGamePanel);
        noGamePanel.setLayout(noGamePanelLayout);
        noGamePanelLayout.setHorizontalGroup(
            noGamePanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, noGamePanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(jLabel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 628, Short.MAX_VALUE)
                .addContainerGap())
        );
        noGamePanelLayout.setVerticalGroup(
            noGamePanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(noGamePanelLayout.createSequentialGroup()
                .add(67, 67, 67)
                .add(jLabel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 95, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(298, Short.MAX_VALUE))
        );

        mainPanel.add(noGamePanel, java.awt.BorderLayout.CENTER);

        menuBar.setName("menuBar"); // NOI18N

        fileMenu.setText(resourceMap.getString("fileMenu.text")); // NOI18N
        fileMenu.setName("fileMenu"); // NOI18N

        newDoubleGameMenu.setText(resourceMap.getString("newDoubleGameMenu.text")); // NOI18N
        newDoubleGameMenu.setName("newDoubleGameMenu"); // NOI18N
        fileMenu.add(newDoubleGameMenu);

        newSingleGameMenu.setText(resourceMap.getString("newSingleGameMenu.text")); // NOI18N
        newSingleGameMenu.setName("newSingleGameMenu"); // NOI18N
        fileMenu.add(newSingleGameMenu);

        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(piccat.view.PicCatApp.class).getContext().getActionMap(PicCatView.class, this);
        closeMenuItem.setAction(actionMap.get("closeGame")); // NOI18N
        closeMenuItem.setAccelerator(getCloseAccelerator());
        closeMenuItem.setText(resourceMap.getString("closeMenuItem.text")); // NOI18N
        closeMenuItem.setName("closeMenuItem"); // NOI18N
        closeMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                closeMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(closeMenuItem);

        exitMenuItem.setAction(actionMap.get("quit")); // NOI18N
        exitMenuItem.setAccelerator(getQuitAccelerator());
        exitMenuItem.setText(resourceMap.getString("exitMenuItem.text")); // NOI18N
        exitMenuItem.setName("exitMenuItem"); // NOI18N
        fileMenu.add(exitMenuItem);

        menuBar.add(fileMenu);

        jMenu1.setText(resourceMap.getString("jMenu1.text")); // NOI18N
        jMenu1.setName("jMenu1"); // NOI18N

        jCheckBoxMenuItem1.setAction(actionMap.get("fullscreen")); // NOI18N
        jCheckBoxMenuItem1.setAccelerator(getFullscreenAccelerator());
        jCheckBoxMenuItem1.setText(resourceMap.getString("jCheckBoxMenuItem1.text")); // NOI18N
        jCheckBoxMenuItem1.setName("jCheckBoxMenuItem1"); // NOI18N
        jMenu1.add(jCheckBoxMenuItem1);

        menuBar.add(jMenu1);

        setComponent(mainPanel);
        setMenuBar(menuBar);
    }// </editor-fold>//GEN-END:initComponents

    private void closeMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeMenuItemActionPerformed
        // TODO add your handling code here:
        closeGame();
        mainPanel.revalidate();
        mainPanel.repaint();

    }//GEN-LAST:event_closeMenuItemActionPerformed

    private class NewGameTask extends Task<JPanel, Void> {

        private String key;
        private int sides;

        public NewGameTask(String key, int sides, Application app) {
            super(app);
            this.key = key;
            this.sides = sides;
        }

        protected JPanel doInBackground() {
            try {
                message("newGameStartMessage");

                closeGame();
//
//                // dump the old game
//                Task t = new CloseGameTask(this.getApplication());
//                t.execute();
//                while (!t.isDone());

                Game game = GameFactory.makeMultiGame(sides, key);
                GameView tmp = new GameView();
                tmp.setModel(game);
                tmp.setDTHandler(dtHandler);

                message("newGameFinishMessage");
                return tmp;
            } catch (GameLoadException ex) {
                String message = "Failed load the game: ";
                LOG.error(message, ex);
                JOptionPane.showMessageDialog(getFrame(), "<html>" + message +
                        "<br />" + ex.getMessage(), "Error",
                        JOptionPane.ERROR_MESSAGE);
                return null;
            }
        }

        @Override
        protected void succeeded(JPanel result) {
            mainPanel.removeAll();
            mainPanel.add(result, BorderLayout.CENTER);
            mainPanel.revalidate();
            mainPanel.repaint();
        }
    }

    private void closeGame() {
        if (gameView != null) {
            gameView.clearModel();
            gameView = null;
        }
        mainPanel.removeAll();
        mainPanel.add(noGamePanel, BorderLayout.CENTER);
    }

    
    @Action
    public void fullscreen() {
        if (fullscreen == null) {
            enableFullscreen();
        } else {
            disableFullscreen();
        }
    }
    private JFrame fullscreen = null;

    public void enableFullscreen() {

        fullscreen = new JFrame();
        fullscreen.setUndecorated(true);
        fullscreen.setResizable(false);

        Component c = getFrame().getContentPane().getComponent(0);
        fullscreen.getContentPane().add(c);
        fullscreen.setJMenuBar(this.getMenuBar());

        GraphicsDevice d = getFrame().getGraphicsConfiguration().getDevice();

        if (!d.isFullScreenSupported())
            System.out.println("Fullscreen not supported");
        d.setFullScreenWindow(fullscreen);
        getFrame().setVisible(false);
        fullscreen.setVisible(true);
        mainPanel.revalidate();
        mainPanel.repaint();
    }

    public void disableFullscreen() {
        Component c = fullscreen.getContentPane().getComponent(0);
        getFrame().getContentPane().removeAll();
        getFrame().getContentPane().add(c);

        getFrame().setVisible(true);
        this.setMenuBar(fullscreen.getJMenuBar());


        GraphicsDevice d = fullscreen.getGraphicsConfiguration().getDevice();
        if (!d.isFullScreenSupported())
            System.out.println("Fullscreen not supported");
        d.setFullScreenWindow(null);
        fullscreen.setVisible(false);
        fullscreen.dispose();
        fullscreen = null;
        mainPanel.revalidate();
        mainPanel.repaint();

    }

    public KeyStroke getFullscreenAccelerator() {
        return KeyStroke.getKeyStroke(KeyEvent.VK_F, KEY_MASK);
    }

    public KeyStroke getCloseAccelerator() {
        return KeyStroke.getKeyStroke(KeyEvent.VK_W, KEY_MASK);
    }

    public KeyStroke getQuitAccelerator() {
        return KeyStroke.getKeyStroke(KeyEvent.VK_Q, KEY_MASK);
    }
//    @Action
//    public Task<?, ?> closeGame() {
//        return new CloseGameTask(getApplication());
//    }
//
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem closeMenuItem;
    private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItem1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JPanel mainPanel;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JMenu newDoubleGameMenu;
    private javax.swing.JMenu newSingleGameMenu;
    private javax.swing.JPanel noGamePanel;
    // End of variables declaration//GEN-END:variables
}
